package assist.client.gwt.view.place;

import java.util.Set;

import assist.domain.model.GamesQuery;
import assist.domain.model.StatsQuery;
import assist.domain.model.StatsQuery.ShotType;
import assist.domain.model.StatsQuery.Strength;
import assist.domain.model.StatsQuery.StatType;
import assist.domain.model.Team;

import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceTokenizer;

public class StatsPlace extends Place
{
    private StatsQuery statsQuery;
    private GamesQuery gamesQuery;
    
    public StatsPlace(GamesQuery gamesQuery, StatsQuery statsQuery)
    {
        this.gamesQuery = gamesQuery;
        this.statsQuery = statsQuery;
    }

    public StatsPlace(GamesQuery gamesQuery)
    {
        this(gamesQuery, null);
    }

    public StatsQuery getStatsQuery()
    {       
        return this.statsQuery;
    }    
    
    public abstract static class Tokenizer<T extends StatsPlace> implements PlaceTokenizer<T>
    {

        @Override
        public String getToken(T place)
        {
            //Tokenize statsQuery.getGameQuery first.
            return SelectGamesPlace.createToken(place.gamesQuery) + "/"
                + createStatsQueryToken(place.statsQuery);
        }

        private String createStatsQueryToken(StatsQuery statsQuery)
        {
            String token = "";
            if (statsQuery == null)
            {
                return token;
            }            
            for (StatsQuery.Column column : statsQuery.getColumns())
            {
                token += "column=" + column.toString() + "&";
            }          
            for (Long playerId : statsQuery.getPlayerIds())
            {
                token += "player=" + playerId + "&";
            }
            for (Long playerId : statsQuery.getPlayerWowyIdsMap().keySet())
            {
                Set<Long> playerWowy = statsQuery.getPlayerWowyIdsMap().get(playerId);
                for (Long wowyPlayer : playerWowy)
                {                
                    token += "wowy=" + playerId + "," + wowyPlayer + "&";
                }
            }             
            return token;
        }
                 

        @Override
        public T getPlace(String token)
        {                        
            GamesQuery gamesQuery = SelectGamesPlace.createGamesQuery(token.split("/")[0]);
            StatsQuery statsQuery = null;
            Team team = gamesQuery.getTeam();
            
            if (token.split("/").length > 1)
            {
                statsQuery = createStatsQuery(token.split("/")[1], team);
            }
            else
            {                
                statsQuery = new StatsQuery(team);
            }
            
            return this.createPlace(gamesQuery, statsQuery);
        }

        private StatsQuery createStatsQuery(String token, Team team)
        {
            StatsQuery statsQuery = new StatsQuery(team);
            String [] params = token.split("&");
            for (String param : params)
            {
                String type = param.split("=")[0];                               
                if (type.equals("column"))
                {
                    String [] values = param.split("=")[1].split(","); 
                    statsQuery.addColumn(new StatsQuery.Column(
                            ShotType.valueOf(values[0]), 
                            Strength.valueOf(values[1]), 
                            StatType.valueOf(values[2]) ));
                }
                if (type.equals("player"))
                {
                    String playerIdStr = param.split("=")[1]; 
                    statsQuery.addPlayerId(new Long(playerIdStr));                    
                }      
                if (type.equals("wowy"))
                {
                    String [] playerIdsStr = param.split("=")[1].split(","); 
                    if (playerIdsStr == null || playerIdsStr.length == 0)
                    {
                        continue;
                    }
                    Long [] playerIds = new Long[playerIdsStr.length];
                    for (int i=0; i<playerIdsStr.length; i++)
                    {
                        playerIds[i] = new Long(playerIdsStr[i]);
                    }
                    statsQuery.addPlayerWowyId(playerIds[0], playerIds[1]);                    
                }                 
            }
            return statsQuery;
        }                
        protected abstract T createPlace(GamesQuery gamesQuery, StatsQuery statsQuery);

    }

    public GamesQuery getGamesQuery()
    {
        // TODO Auto-generated method stub
        return this.gamesQuery;
    }    
}
